﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Casamiel.API.Application.Models;
using Casamiel.API.Application.Services;
using Casamiel.Application;
using Casamiel.Common;
using Casamiel.Domain;
using Casamiel.Domain.Entity;
using Enyim.Caching;
using MediatR;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Casamiel.API.Application.Commands
{
    /// <summary>
    /// 
    /// </summary>
    public sealed class MemberIcselfregistCommandHandler : IRequestHandler<MemberIcselfregistCommand, Zmodel>
    {
        private readonly IMemcachedClient _memcachedClient;
        private readonly IMemberService _memberService;
        private readonly IMemberCardService _memberCard;
        private readonly string _memcachedPrex;
        private readonly IIcApiService _iicApiService;
        private readonly IUserLogService _userLogService;
        private readonly NLog.ILogger logger = NLog.LogManager.GetLogger("BizInfo");
        /// <summary>
        /// 
        /// </summary>
        /// <param name="casamielSettings"></param>
        /// <param name="memcachedClient"></param>
        /// <param name="memberCardService"></param>
        /// <param name="memberService"></param>
        /// <param name="iicApiService"></param>
        /// <param name="userLogService"></param>
        public MemberIcselfregistCommandHandler(IOptionsSnapshot<CasamielSettings> casamielSettings, IMemcachedClient memcachedClient, IMemberCardService memberCardService, IMemberService memberService, IIcApiService iicApiService, IUserLogService userLogService)
        {
            if (casamielSettings == null) {
                throw new ArgumentNullException(nameof(casamielSettings));
            }

            _memcachedClient = memcachedClient;
            _memberCard = memberCardService;
            _memberService = memberService;
            _memcachedPrex = casamielSettings.Value.MemcachedPre;
            _iicApiService = iicApiService;
            _userLogService = userLogService;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<Zmodel> Handle(MemberIcselfregistCommand request, CancellationToken cancellationToken)
        {
            if (request == null) {
                throw new ArgumentNullException(nameof(request));
            }

            var cardlist = await _memberCard.GetListAsync<ICasaMielSession>(request.Mobile).ConfigureAwait(false);// _context.MemberCard.Where(c => c.Mobile == mobile && c.IsBind == true);
                                                                                                                  //	var trynum = 0;                                                                                 //  trynum += _memcachedClient.GetWithCas<int>(_memcachedPrex + "Icselfregist" + mobile).Result;
                                                                                                                  //var da = new Enyim.Caching.Memcached.CasResult<object>();
            var _cachekey = _memcachedPrex + Constant.ICSELFREGIST + request.Mobile;
             
            var trynum = _memcachedClient.Increment(_cachekey, 1, 1);
            var memberInfo = await _memberService.FindAsync<ICasaMielSession>(request.Mobile).ConfigureAwait(false);

            if (trynum > 1) {
                logger.Trace($"MemberIcselfregistCommand:{JsonConvert.SerializeObject(trynum)},{_cachekey}");
                var newcard = cardlist.SingleOrDefault(c => c.IsBind == true && (c.CardType == "2" || c.CardType == "1"));
                if (newcard != null) {

                    return new Zmodel { code = 0, msg = "会员卡申请成功" };//, content = new { cardno = newcard.CardNo } };//, cardno = newcard.CardNo };
                }
                return new Zmodel { code = 999, msg = "请重试" };
            }
            if (cardlist.Any(c => c.IsBind == true && (c.CardType == "1" || c.CardType == "2"))) {
                _memcachedClient.Remove(_cachekey);
                return new Zmodel { code = -12, msg = "已有会员卡不能再申请" };
            }
            Zmodel result;
            try {
              result = await _iicApiService.Icselfregist(request.Mobile, request.Source).ConfigureAwait(false);
            } catch (Exception ex) {
                _memcachedClient.Remove(_cachekey);
                throw ex;
            }
            var rnt = JsonConvert.DeserializeObject<JObject>(result.content);
            if (result.code == 0) {
                if (memberInfo == null) {
                    memberInfo = new Member { Mobile = request.Mobile, Source = request.Source, CreateDate = DateTime.Now };
                    await _memberService.AddAsync<ICasaMielSession>(memberInfo).ConfigureAwait(false);
                }
                //_cacheService.Remove(Infrastructure.Constant.MYCARDS_PREFIX + mobile);
                // await _memcachedClient.RemoveAsync(_memcachedPrex+ Constant.MYCARDS_PREFIX + mobile);
                var mcard = await _memberCard.FindAsync<ICasaMielSession>(rnt["cardno"].ToString(), request.Mobile).ConfigureAwait(false);
                if (mcard == null) {
                    mcard = new MemberCard {
                        M_ID = memberInfo.ID,
                        CardNO = rnt["cardno"].ToString(),
                        Mobile = request.Mobile,
                        IsBind = true,
                        CardType = "2",
                        BindTime = DateTime.Now,
                        Source = request.Source,
                        CreateTime = DateTime.Now
                    };

                    try {
                        await _memberCard.AddAsync<ICasaMielSession>(mcard).ConfigureAwait(false);
                        //await _memberCard.UnitOfWork.SaveEntitiesAsync();
                          var logdata = new UserLog { Url =request.RequestUrl, OPInfo = $"申请会员卡,卡号:[{rnt["cardno"].ToString()}]", OPTime = DateTime.Now, UserName = request.Mobile, UserIP = request.UserIP };
                          await _userLogService.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
                    } catch (SqlException ex) {
                        _memcachedClient.Remove(_cachekey);
                        if (ex.Number != 2601) {
                            throw;
                        }
                    }
                } else {
                    mcard.IsBind = true;
                    mcard.M_ID = memberInfo.ID;
                    mcard.BindTime = DateTime.Now;
                    mcard.Source = request.Source;
                    await _memberCard.UpdateAsync<ICasaMielSession>(mcard).ConfigureAwait(false);
                    //await _memberCard.UnitOfWork.SaveChangesAsync();
                    var logdata = new UserLog { Url = request.RequestUrl, OPInfo = $"重新申请会员卡,卡号:[{rnt["cardno"].ToString()}]", OPTime = DateTime.Now, UserName = request.Mobile, UserIP = request.UserIP };
                    await _userLogService.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
                }
                _memcachedClient.Remove(_cachekey);
                return new Zmodel { code = 0, msg = "会员卡申请成功" };// content = new { cardno = mcard.CardNo }, cardno = mcard.CardNo });
            } else {
                _memcachedClient.Remove(_cachekey);
            }
            //_memcachedClient.Remove(_cachekey);
            return result;
        }
    }
}
